﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Web.Helper;
using Web.Security;
using RentalSystem.Data.EF;
using RentalSystem.Data.EF.Core;
using Web.Models;

namespace Web.Controllers
{
    [Authorize(Roles = RoleType.Customer)]
    public class CustomersController : BaseController
    {
        [HttpGet]
        public ActionResult Index()
        {
            List<Hires> currentHire = DataContext.HiresDao.GetCustomerCurrentHire(CurrentUser.Guid);

            LoadErrorsAndSuccessFromAnotherPage();
            return View(currentHire);
        }

        [HttpGet]
        public ActionResult SelectAgency(int agencyId)
        {
            Agencies agency = DataContext.AgenciesDao.Get(agencyId);

            if (agency == null)
            {
                ShowErrorOnAnotherPage("Podana agencja nie istnieje");
                return RedirectToAction("Locations", "Public");
            }

            if (!agency.AgencyIsActive)
            {
                ShowErrorOnAnotherPage("Agencja aktualnie jest nieaktywna");
                return RedirectToAction("Locations", "Public");
            }

            Users user = DataContext.UsersDao.Get(CurrentUser.Guid);

            if (user == null)
            {
                ShowErrorOnAnotherPage("Aby wybrać agencję musisz się zalogować");
                return RedirectToAction("Locations", "Public");
            }

            user.AgencyId = agencyId;
            DataContext.UsersDao.Update(user, (uint)UserFields.Agency);
            LogManager.CustomerSelectLocation(CurrentUser.Guid, String.Format("Wybrana agencja: {0}",agency.AgencyName));

            ShowSuccessOnAnotherPage("Poprawnie przypisano lokalizacje do Twojego konta. Możesz teraz wypożyczać filmy.");
            return RedirectToAction("Locations", "Public");
        }

        [HttpGet]
        public ActionResult RentHistory(int page = 1)
        {
            int pageSize = SettingsManager.SmallItemsCountOnPages;
            Users user = DataContext.UsersDao.Get(CurrentUser.Guid);

            if (user == null)
            {
                ShowError("Nie odnaleziono użytkownika");
                return View();
            }

            MovieHiresListViewModel model = new MovieHiresListViewModel 
            {
                Hires = user.Hires.OrderByDescending(x=> x.HirePlanningReturningDate).Skip((page - 1) * pageSize).Take(pageSize),
                PagingInfo = new PagingInfo(page, pageSize, user.Hires.Count)
            };

            return View(model);
        }

        [HttpGet]
        public ActionResult RentCash(int page = 1)
        {
            int pageSize = SettingsManager.SmallItemsCountOnPages;
            Users user = DataContext.UsersDao.Get(CurrentUser.Guid);

            if (user == null)
            {
                ShowError("Nie odnaleziono użytkownika");
                return View();
            }

            List<string> msg = new List<string>();
            float payed = 0;
            float toPay = 0;
            float bestHire = 0;
            float penaltiesCash = 0;

            foreach (Hires hire in user.Hires)
            {
                float hireValue = (float)(hire.HireLateReward + hire.HirePlanningCost);
                penaltiesCash += (float)(hire.HireLateReward);
                if (hireValue > bestHire)
                    bestHire = hireValue;
                if (!hire.HireIsDiscReturned)
                    toPay += hireValue;
                else
                    payed += hireValue;
            }

            msg.Add(String.Format("Suma wszystkich wypożyczeń to {0} zł",payed + toPay));
            msg.Add(String.Format("Zapłacono - {0} zł", payed));
            msg.Add(String.Format("Niezapłacono - {0} zł", toPay));
            msg.Add(String.Format("Najdroższe wypożyczenie - {0} zł", bestHire));
            msg.Add(String.Format("Naliczone kary za przetrzymanie nośników - {0} zł", penaltiesCash));

            FinancesViewModel model = new FinancesViewModel
            {
                Hires = user.Hires.OrderByDescending(x => x.HirePlanningReturningDate).Skip((page - 1) * pageSize).Take(pageSize).ToList(),
                Messages = msg,
                PagingInfo = new PagingInfo(page, pageSize, user.Hires.Count)
            };

            return View(model);
        }

        [HttpGet]
        public ActionResult Settings()
        {
            Users user = DataContext.UsersDao.Get(CurrentUser.Guid);

            UserSettingsViewModel model = new UserSettingsViewModel()
            {
                AgencyName = user.Agencies.AgencyName,
                CommentsCount = user.Comments.Count,
                HiresCount = user.Hires.Count,
                UserDateCreated = user.UserDateCreated,
                UserDisplayName = user.UserDisplayName,
                UserEmail = user.UserEmail,
                VotesCount = user.Votes.Count
            };

            LoadErrorsAndSuccessFromAnotherPage();
            return View(model);
        }

        [HttpPost]
        public ActionResult Settings(UserSettingsViewModel model)
        {
            if (model == null || !ModelState.IsValid)
            {
                ShowError("Niepoprawne dane!");
                return View(model);
            }

            Users user = DataContext.UsersDao.Get(CurrentUser.Guid);
            user.UserDisplayName = model.UserDisplayName;
            if (!String.IsNullOrEmpty(model.UserPassword))
                user.UserPassword = Helper.Crypto.ComputeMD5(model.UserPassword);

            DataContext.UsersDao.Update(user, (uint)(UserFields.DisplayName|UserFields.PasswordHash));

            ShowSuccessOnAnotherPage("Zapisano zmiany!");
            return RedirectToAction("Settings");
        }

        [HttpGet]
        public ActionResult History(int page = 1)
        {
            int pageSize = SettingsManager.SmallItemsCountOnPages;
            List<UserLogs> logsFromDb = DataContext.UserLogsDao.ListByUser(CurrentUser.Guid);

            LogsListViewModel model = new LogsListViewModel()
            {
                logs = logsFromDb.OrderByDescending(x => x.UserLogDate).Skip((page - 1) * pageSize).Take(pageSize).ToList(),
                PagingInfo = new PagingInfo(page, pageSize, logsFromDb.Count)
            };

            return View(model);
        }
    }
}
